package edu.ubc.javascript;

import com.google.javascript.jscomp.mozilla.rhino.Token;
import com.google.javascript.jscomp.mozilla.rhino.ast.Assignment;
import com.google.javascript.jscomp.mozilla.rhino.ast.AstNode;
import com.google.javascript.jscomp.mozilla.rhino.ast.FunctionCall;
import com.google.javascript.jscomp.mozilla.rhino.ast.InfixExpression;
import com.google.javascript.jscomp.mozilla.rhino.ast.Name;
import com.google.javascript.jscomp.mozilla.rhino.ast.NodeVisitor;
import com.google.javascript.jscomp.mozilla.rhino.ast.PropertyGet;

public class GetSet implements NodeVisitor {
	
private ReflectiveAstTransformer tx;
	
	public GetSet(ReflectiveAstTransformer tx) {
		this.tx = tx;
	}
	
	private int count = 0;
	
	private String newName() {
		return "_tmp" + (count++);
	}
	
	@Override
	public boolean visit(AstNode astNode) {
		if((astNode instanceof PropertyGet) || (astNode.getType() == Token.GETPROP)) {
			PropertyGet pg = (PropertyGet) astNode;
			AstNode right = pg.getRight();
			if(pg.getParent().getType() == Token.ASSIGN) {
				InfixExpression infix = (InfixExpression) pg.getParent();
				if(infix.getLeft() == pg) {
					if(pg.getRight() instanceof Name) {
						Name name = (Name) pg.getRight();
						if(pg.getLeft() instanceof PropertyGet) {
							PropertyGet pgLeft = (PropertyGet) pg.getLeft();
							Name nameLeft = (Name) pgLeft.getRight();
							if(nameLeft.getString().equals("prototype")) {
								return false;
							}
						}
						if(pg.getLeft() instanceof Name) {
							Name leftName = (Name) pg.getLeft();
							Tag scope = TagManager.getUniqueTag(leftName, "scope");
							String value = (String) scope.getValue();
							if(value.equals("local")) {
								return true;
							}
						}
						FunctionCall call = ASTFactory.call("___setter", pg.getLeft(), ASTFactory.name("'" + name.getString() + "'"), infix.getRight());
						tx.replaceNode(infix.getParent(), infix, call);
					}
				}
				return false;
			} else {
					if(pg.getLeft() instanceof com.google.javascript.jscomp.mozilla.rhino.ast.RegExpLiteral) {
						return false;
					}
					if(pg.getLeft() instanceof com.google.javascript.jscomp.mozilla.rhino.ast.NewExpression) {
						return false;
					}
					if(pg.getLeft() instanceof com.google.javascript.jscomp.mozilla.rhino.ast.ParenthesizedExpression) {
						return false;
					}
					if(pg.getRight() instanceof Name) {
						Name newName = ASTFactory.name(newName());
						PropertyGet newPG = new PropertyGet();
						newPG.setLeft(pg.getLeft());
						newPG.setRight(pg.getRight());
						Assignment assign = ASTFactory.assign(newName, newPG.getLeft());
						Name name = (Name) pg.getRight();
						FunctionCall call = ASTFactory.call("___getter", newPG.getLeft(), ASTFactory.name("'" + name.getString() + "'"));
						if(pg.getParent().getParent() != null) {
						//	tx.replaceNode(pg.getParent(), pg, call);
						}
					}
				
				return false;
				/*Name name = ASTFactory.name(newName());
				Assignment assign = ASTFactory.assign(name, pg);
				FunctionCall call = ASTFactory.call("_getter", name, pg.getLeft(), ASTFactory.name("'" + name.getString() + "'"));
				InfixExpression comma = ASTFactory.comma(assign, call);
				tx.replaceNode(astNode.getParent(), astNode, ASTFactory.name("foofo"));
				return false;*/
			}
		}
		return true;
	}
	
}
